package com.coderfans.serialize;

import com.caucho.hessian.io.HessianInput;
import com.caucho.hessian.io.HessianOutput;
import com.caucho.hessian.io.SerializerFactory;
import com.coderfans.exception.SerializeException;
import org.apache.commons.lang.SerializationException;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * Created by ${fanchunshuai} on 2016-9-22.
 *
 * @version: V1.0
 * @Desc:
 * @Copyright (c) 2016 58到家-版权所有
 */
public class HessianSerialize implements ISerialize<Object> {

    private static SerializerFactory serializerFactory;

    private static SerializerFactory getSerializerFactory(){
        serializerFactory = new SerializerFactory();
        return serializerFactory;
    }

    static public HessianInput createHessianInput(InputStream in) {
        HessianInput hin = new HessianInput(in);
        hin.setSerializerFactory(serializerFactory);
        return hin;
    }

    @Override
    public  byte[] serialize(Object o) throws SerializeException{
        if(o == null){
            throw new SerializeException("object is null,can't be hessian serialized.");
        }
        byte [] result = null;
        ByteArrayOutputStream bos = null;
        HessianOutput hessianSerializerOutput = null;
        try {
            bos = new ByteArrayOutputStream();
            hessianSerializerOutput = new HessianOutput(bos);
            hessianSerializerOutput.setSerializerFactory(getSerializerFactory());
            //write本身是线程安全的
            hessianSerializerOutput.writeObject(o);
            bos.close();
            result = bos.toByteArray();
            hessianSerializerOutput.close();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(bos != null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    @Override
    public Object disSerialize(Class clazz, byte[] objectByte) throws SerializeException{
        if(objectByte == null){
            throw  new NullPointerException();
        }
        Object result = null;
        ByteArrayInputStream bis = null;
        HessianInput hessianInput = null;
        try {
            bis = new ByteArrayInputStream(objectByte);

            hessianInput = new HessianInput(bis);
            hessianInput.setSerializerFactory(getSerializerFactory());
            result =  hessianInput.readObject(clazz.getClass());
            bis.close();
            hessianInput.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new SerializeException(e.getMessage());
        }finally {
            if(bis != null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            hessianInput.close();
        }
        return result;

    }
}
